{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true,
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "<p align=\"center\">\n",
    "    <img src=\"https://github.com/GeostatsGuy/GeostatsPy/blob/master/TCG_color_logo.png?raw=true\" width=\"220\" height=\"240\" />\n",
    "\n",
    "</p>\n",
    "\n",
    "# Data Analytics Basics in Python Series\n",
    "\n",
    "## Chapter I: Pandas DataFrames for Working with Tabular Data in Python \n",
    "\n",
    "### Michael Pyrcz, Associate Professor, The University of Texas at Austin \n",
    "\n",
    "*Novel Data Analytics, Geostatistics and Machine Learning Subsurface Solutions*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "#### Tabular Data\n",
    "\n",
    "This is a tutorial for / demonstration of **Tabular Data Structures in Python**.  In Python, the common tool for dealing with Tabular Data Structures is the DataFrame from the pandas Python package. \n",
    "\n",
    "This tutorial includes the methods and operations that would commonly be required for Engineers and Scientists working with Tabular Data Structures for the purpose of:\n",
    "\n",
    "1. Data Checking and Cleaning\n",
    "2. Data Mining / Inferential Data Analysis\n",
    "3. Data Analytics / Building Predictive Models with Geostatistics and Machine Learning\n",
    "\n",
    "Learning to work with Pandas DataFrames is essential for dealing with tabular data (e.g. well data) in subsurface modeling workflows and for subsurface machine learning."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "##### Tabular Data Structures\n",
    "\n",
    "In Python we will commonly store our data in two formats, tables and arrays.  For sample data with typically multiple features $1,\\ldots,m$ over $1,\\ldots,n$ samples we work with tables.  For exhaustive maps and models usually representing a single feature on a regular grid over $1,\\ldots,n_{i}$ for $i = 1,\\ldots,n_{dim}$ we will work with arrays.\n",
    "\n",
    "| $X^1$       | $X^2$       | $\\ldots$    | $X^m$       | $y$       |\n",
    "| ----------- | ----------- | ----------- | ----------- | --------- |\n",
    "| $X^1_1$     | $X^2_1$     | $\\ldots$    | $X^m_1$     | $y_1$     |\n",
    "| $X^1_2$     | $X^2_2$     | $\\ldots$    | $X^m_2$     | $y_2$     |\n",
    "| $\\ldots$    | $\\ldots$    | $\\ldots$    | $\\ldots$    | $\\ldots$  |\n",
    "| $X^1_n$     | $X^2_n$     | $\\ldots$    | $X^m_n$     | $y_n$     |\n",
    "\n",
    "\n",
    "**pandas** package provides a convenient DataFrame object for working with data in a table and numpy package provides a convenient ndarray object for working with gridded data. In the following tutorial we will focus on DataFrames although we will utilize ndarrays a couple of times.  There is another section on Gridded Data Structures that focuses on ndarrays."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "#### Project Goal\n",
    "\n",
    "Learn the basics for working with Tabular Data Structures in Python with pandas DataFrames.\n",
    "\n",
    "#### Load the required libraries\n",
    "\n",
    "The following code loads the required libraries."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "slideshow": {
     "slide_type": "-"
    }
   },
   "outputs": [],
   "source": [
    "import os                                       # operating system \n",
    "import numpy as np                              # arrays and matrix math\n",
    "import pandas as pd                             # DataFrames\n",
    "import matplotlib.pyplot as plt                 # plotting"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "-"
    }
   },
   "source": [
    "If you get a package import error, you may have to first install some of these packages. This can usually be accomplished by opening up a command window on Windows and then typing 'python -m pip install [package-name]'. More assistance is available with the respective package docs.  \n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "#### Set the working directory\n",
    "\n",
    "I always like to do this so I don't lose files and to simplify subsequent read and writes (avoid including the full address each time).  Also, in this case make sure to place the required (see below) data file in this directory.  When we are done with this tutorial we will write our new dataset back to this directory.  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "slideshow": {
     "slide_type": "-"
    }
   },
   "outputs": [],
   "source": [
    "os.chdir(\"c:/PGE383\")                           # set working directory"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "#### Loading Data \n",
    "\n",
    "Let's load the provided multivariate, spatial dataset.  '2D_MV_200wells.csv' is available at https://github.com/GeostatsGuy/GeoDataSets.  It is a comma delimited file with X and Y coordinates,facies 1 and 2 (1 is sandstone and 2 interbedded sand and mudstone), porosity (fraction), permeability (mDarcy) and acoustic impedance (kg/m2s*10^6). We load it with the pandas 'read_csv' function into a data frame we called 'df' and then preview it by printing a slice and by utilizing the 'head' DataFrame member function (with a nice and clean format, see below)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "slideshow": {
     "slide_type": "-"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>X</th>\n",
       "      <th>Y</th>\n",
       "      <th>facies_threshold_0.3</th>\n",
       "      <th>porosity</th>\n",
       "      <th>permeability</th>\n",
       "      <th>acoustic_impedance</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>565</td>\n",
       "      <td>1485</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1184</td>\n",
       "      <td>6.170</td>\n",
       "      <td>2.009</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2585</td>\n",
       "      <td>1185</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1566</td>\n",
       "      <td>6.275</td>\n",
       "      <td>2.864</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2065</td>\n",
       "      <td>2865</td>\n",
       "      <td>2</td>\n",
       "      <td>0.1920</td>\n",
       "      <td>92.297</td>\n",
       "      <td>3.524</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>3575</td>\n",
       "      <td>2655</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1621</td>\n",
       "      <td>9.048</td>\n",
       "      <td>2.157</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1835</td>\n",
       "      <td>35</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1766</td>\n",
       "      <td>7.123</td>\n",
       "      <td>3.979</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      X     Y  facies_threshold_0.3  porosity  permeability  \\\n",
       "0   565  1485                     1    0.1184         6.170   \n",
       "1  2585  1185                     1    0.1566         6.275   \n",
       "2  2065  2865                     2    0.1920        92.297   \n",
       "3  3575  2655                     1    0.1621         9.048   \n",
       "4  1835    35                     1    0.1766         7.123   \n",
       "\n",
       "   acoustic_impedance  \n",
       "0               2.009  \n",
       "1               2.864  \n",
       "2               3.524  \n",
       "3               2.157  \n",
       "4               3.979  "
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#df = pd.read_csv(\"2D_MV_200wells.csv\")          # read in DataFrame (.csv)\n",
    "df = pd.read_csv(\"https://raw.githubusercontent.com/GeostatsGuy/GeoDataSets/master/2D_MV_200wells.csv\")\n",
    "#print(df.iloc[0:5,:])                          # view the first 5 samples\n",
    "df.head()                                       # view the first 5 samples"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "#### Check the Tabular Data\n",
    "\n",
    "It is useful to review the summary statistics of our loaded DataFrame.  That can be accomplished with the 'describe' DataFrame member function.  We transpose to switch the axes for ease of visualization."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "slideshow": {
     "slide_type": "-"
    }
   },
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'df' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-1-64e532c4f2a5>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mdf\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdescribe\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m                                   \u001b[1;31m# summary statistics\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mNameError\u001b[0m: name 'df' is not defined"
     ]
    }
   ],
   "source": [
    "df.describe()                                   # summary statistics"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Rename Features\n",
    "\n",
    "Let's rename the facies, permeability and acoustic impedance for convenience."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>X</th>\n",
       "      <th>Y</th>\n",
       "      <th>facies</th>\n",
       "      <th>porosity</th>\n",
       "      <th>perm</th>\n",
       "      <th>ai</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>565</td>\n",
       "      <td>1485</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1184</td>\n",
       "      <td>6.170</td>\n",
       "      <td>2.009</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2585</td>\n",
       "      <td>1185</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1566</td>\n",
       "      <td>6.275</td>\n",
       "      <td>2.864</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2065</td>\n",
       "      <td>2865</td>\n",
       "      <td>2</td>\n",
       "      <td>0.1920</td>\n",
       "      <td>92.297</td>\n",
       "      <td>3.524</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>3575</td>\n",
       "      <td>2655</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1621</td>\n",
       "      <td>9.048</td>\n",
       "      <td>2.157</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1835</td>\n",
       "      <td>35</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1766</td>\n",
       "      <td>7.123</td>\n",
       "      <td>3.979</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      X     Y  facies  porosity    perm     ai\n",
       "0   565  1485       1    0.1184   6.170  2.009\n",
       "1  2585  1185       1    0.1566   6.275  2.864\n",
       "2  2065  2865       2    0.1920  92.297  3.524\n",
       "3  3575  2655       1    0.1621   9.048  2.157\n",
       "4  1835    35       1    0.1766   7.123  3.979"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = df.rename(columns={'facies_threshold_0.3': 'facies','permeability':'perm','acoustic_impedance':'ai'}) # rename columns of the \n",
    "df.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Slicing DataFrames\n",
    "\n",
    "It is straightforward to extract subsets from a DataFrame to make a new DataFrame. \n",
    "\n",
    "* We use [my_DataFrame].iloc() with indexes, integers for rows and columns \n",
    "\n",
    "* This is useful for cleaning up data by removing features that are no longer of interest.\n",
    "\n",
    "* Below we make a new DataFrame, 'df_subset', with the rows 0 to 4 and columns 2 to 6 and another new DataFrame, 'df_subset;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>facies</th>\n",
       "      <th>porosity</th>\n",
       "      <th>perm</th>\n",
       "      <th>ai</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>0.1184</td>\n",
       "      <td>6.170</td>\n",
       "      <td>2.009</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>0.1566</td>\n",
       "      <td>6.275</td>\n",
       "      <td>2.864</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2</td>\n",
       "      <td>0.1920</td>\n",
       "      <td>92.297</td>\n",
       "      <td>3.524</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>1</td>\n",
       "      <td>0.1621</td>\n",
       "      <td>9.048</td>\n",
       "      <td>2.157</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1</td>\n",
       "      <td>0.1766</td>\n",
       "      <td>7.123</td>\n",
       "      <td>3.979</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   facies  porosity    perm     ai\n",
       "0       1    0.1184   6.170  2.009\n",
       "1       1    0.1566   6.275  2.864\n",
       "2       2    0.1920  92.297  3.524\n",
       "3       1    0.1621   9.048  2.157\n",
       "4       1    0.1766   7.123  3.979"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_subset = df.iloc[0:5,2:7]                    # new DataFrame as a slice\n",
    "df_subset.head(n=10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "   facies  porosity    perm     ai\n",
      "0       1    0.1184   6.170  2.009\n",
      "1       1    0.1566   6.275  2.864\n",
      "2       2    0.1920  92.297  3.524\n",
      "3       1    0.1621   9.048  2.157\n",
      "4       1    0.1766   7.123  3.979\n"
     ]
    }
   ],
   "source": [
    "df_subset = df.iloc[0:5,2:7]                                # make a new dataframe with just the first 4 samples and no X,Y\n",
    "#df_subset.head()\n",
    "print(df_subset)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Slicing DataFrames\n",
    "\n",
    "It is straightforward to extract subsets from a DataFrame to make a new DataFrame. \n",
    "\n",
    "* We use [my_DataFrame].loc() with column labels and integers for rows, could be more legible \n",
    "\n",
    "* This is useful for cleaning up data by removing features that are no longer of interest.\n",
    "\n",
    "* Below we make a new DataFrame, 'df_subset', with the rows 0 to 4 and columns X, facies, porosity and perm to another new DataFrame, 'df_subset2'."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>X</th>\n",
       "      <th>Y</th>\n",
       "      <th>facies</th>\n",
       "      <th>porosity</th>\n",
       "      <th>perm</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>565</td>\n",
       "      <td>1485</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1184</td>\n",
       "      <td>6.170</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2585</td>\n",
       "      <td>1185</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1566</td>\n",
       "      <td>6.275</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2065</td>\n",
       "      <td>2865</td>\n",
       "      <td>2</td>\n",
       "      <td>0.1920</td>\n",
       "      <td>92.297</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>3575</td>\n",
       "      <td>2655</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1621</td>\n",
       "      <td>9.048</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1835</td>\n",
       "      <td>35</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1766</td>\n",
       "      <td>7.123</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      X     Y  facies  porosity    perm\n",
       "0   565  1485       1    0.1184   6.170\n",
       "1  2585  1185       1    0.1566   6.275\n",
       "2  2065  2865       2    0.1920  92.297\n",
       "3  3575  2655       1    0.1621   9.048\n",
       "4  1835    35       1    0.1766   7.123"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_subset2 = df.loc[:4,['X','Y','facies','porosity','perm']]                    # new DataFrame as a slice\n",
    "df_subset2.head(n=10)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Deep and Shallow Copies\n",
    "\n",
    "We must know the difference, or we will eventually run into an issue.\n",
    "\n",
    "* **shallow copy** - point to the same memory, change one and both are changed\n",
    "\n",
    "* **deep copy** - make a new copy in memory, change one only one changes\n",
    "\n",
    "#### Deep Copy Example \n",
    "\n",
    "Let's demonstrate a deep copy with the DataFrame member function, [my_DataFrame].copy()\n",
    "\n",
    "* note, the [my_DataFrame].loc() member function is a deep copy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>X</th>\n",
       "      <th>Y</th>\n",
       "      <th>facies</th>\n",
       "      <th>porosity</th>\n",
       "      <th>perm</th>\n",
       "      <th>ai</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>565</td>\n",
       "      <td>1485</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1184</td>\n",
       "      <td>6.170</td>\n",
       "      <td>2.009</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2585</td>\n",
       "      <td>1185</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1566</td>\n",
       "      <td>6.275</td>\n",
       "      <td>2.864</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2065</td>\n",
       "      <td>2865</td>\n",
       "      <td>2</td>\n",
       "      <td>0.1920</td>\n",
       "      <td>92.297</td>\n",
       "      <td>3.524</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>3575</td>\n",
       "      <td>2655</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1621</td>\n",
       "      <td>9.048</td>\n",
       "      <td>2.157</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1835</td>\n",
       "      <td>35</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1766</td>\n",
       "      <td>7.123</td>\n",
       "      <td>3.979</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      X     Y  facies  porosity    perm     ai\n",
       "0   565  1485       1    0.1184   6.170  2.009\n",
       "1  2585  1185       1    0.1566   6.275  2.864\n",
       "2  2065  2865       2    0.1920  92.297  3.524\n",
       "3  3575  2655       1    0.1621   9.048  2.157\n",
       "4  1835    35       1    0.1766   7.123  3.979"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_deep_copy = df.copy(deep = True)             # deep copy of the DataFrame\n",
    "df_deep_copy.loc[4,'ai'] = 4.0                  # change a value in the copy and check original\n",
    "df.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Shallow Copy Example\n",
    "\n",
    "Let's demonstrate a shallow copy with the DataFrame member function, [my_DataFrame].copy()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>X</th>\n",
       "      <th>Y</th>\n",
       "      <th>facies</th>\n",
       "      <th>porosity</th>\n",
       "      <th>perm</th>\n",
       "      <th>ai</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>565</td>\n",
       "      <td>1485</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1184</td>\n",
       "      <td>6.170</td>\n",
       "      <td>2.009</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2585</td>\n",
       "      <td>1185</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1566</td>\n",
       "      <td>6.275</td>\n",
       "      <td>2.864</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2065</td>\n",
       "      <td>2865</td>\n",
       "      <td>2</td>\n",
       "      <td>0.1920</td>\n",
       "      <td>92.297</td>\n",
       "      <td>3.524</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>3575</td>\n",
       "      <td>2655</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1621</td>\n",
       "      <td>9.048</td>\n",
       "      <td>2.157</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1835</td>\n",
       "      <td>35</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1766</td>\n",
       "      <td>7.123</td>\n",
       "      <td>4.000</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      X     Y  facies  porosity    perm     ai\n",
       "0   565  1485       1    0.1184   6.170  2.009\n",
       "1  2585  1185       1    0.1566   6.275  2.864\n",
       "2  2065  2865       2    0.1920  92.297  3.524\n",
       "3  3575  2655       1    0.1621   9.048  2.157\n",
       "4  1835    35       1    0.1766   7.123  4.000"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_shallow_copy = df.copy(deep = False)         # deep copy of the DataFrame\n",
    "df_shallow_copy.loc[4,'ai'] = 4.0               # change a value in the copy and check the original\n",
    "df.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Add a New Feature\n",
    "\n",
    "It is also easy to add a column to our data frame.  \n",
    "\n",
    "* Note, we assume that the array is in the same order as the samples in the DataFrame.  \n",
    "\n",
    "This could be an issue if any rows were removed form either before adding etc.  To demonstrate we make a 1D numpy array of zeros using the 'zeros' function and add it to our DataFrame with the feature name indicated as 'zero'."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>X</th>\n",
       "      <th>Y</th>\n",
       "      <th>facies</th>\n",
       "      <th>porosity</th>\n",
       "      <th>perm</th>\n",
       "      <th>ai</th>\n",
       "      <th>zero</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>565</td>\n",
       "      <td>1485</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1184</td>\n",
       "      <td>6.170</td>\n",
       "      <td>2.009</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2585</td>\n",
       "      <td>1185</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1566</td>\n",
       "      <td>6.275</td>\n",
       "      <td>2.864</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2065</td>\n",
       "      <td>2865</td>\n",
       "      <td>2</td>\n",
       "      <td>0.1920</td>\n",
       "      <td>92.297</td>\n",
       "      <td>3.524</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>3575</td>\n",
       "      <td>2655</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1621</td>\n",
       "      <td>9.048</td>\n",
       "      <td>2.157</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1835</td>\n",
       "      <td>35</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1766</td>\n",
       "      <td>7.123</td>\n",
       "      <td>4.000</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      X     Y  facies  porosity    perm     ai  zero\n",
       "0   565  1485       1    0.1184   6.170  2.009   0.0\n",
       "1  2585  1185       1    0.1566   6.275  2.864   0.0\n",
       "2  2065  2865       2    0.1920  92.297  3.524   0.0\n",
       "3  3575  2655       1    0.1621   9.048  2.157   0.0\n",
       "4  1835    35       1    0.1766   7.123  4.000   0.0"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "zeros = np.zeros(200)                                       # make a array of zeros\n",
    "df['zero'] = pd.Series(zeros)                               # add the array to our DataFrame\n",
    "df.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Remove a Feature\n",
    "\n",
    "We can also remove features from the DataFrame.  \n",
    "\n",
    "* We do this with the member function, [my_DataFrame].drop()\n",
    "\n",
    "* We just have the give the column name and by indicating axis=1 we specify to drop a column."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>X</th>\n",
       "      <th>Y</th>\n",
       "      <th>facies</th>\n",
       "      <th>porosity</th>\n",
       "      <th>perm</th>\n",
       "      <th>ai</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>565</td>\n",
       "      <td>1485</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1184</td>\n",
       "      <td>6.170</td>\n",
       "      <td>2.009</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2585</td>\n",
       "      <td>1185</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1566</td>\n",
       "      <td>6.275</td>\n",
       "      <td>2.864</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2065</td>\n",
       "      <td>2865</td>\n",
       "      <td>2</td>\n",
       "      <td>0.1920</td>\n",
       "      <td>92.297</td>\n",
       "      <td>3.524</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>3575</td>\n",
       "      <td>2655</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1621</td>\n",
       "      <td>9.048</td>\n",
       "      <td>2.157</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1835</td>\n",
       "      <td>35</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1766</td>\n",
       "      <td>7.123</td>\n",
       "      <td>4.000</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      X     Y  facies  porosity    perm     ai\n",
       "0   565  1485       1    0.1184   6.170  2.009\n",
       "1  2585  1185       1    0.1566   6.275  2.864\n",
       "2  2065  2865       2    0.1920  92.297  3.524\n",
       "3  3575  2655       1    0.1621   9.048  2.157\n",
       "4  1835    35       1    0.1766   7.123  4.000"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = df.drop('zero',axis=1)                     # remove the zero column\n",
    "df.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Remove a Sample\n",
    "\n",
    "We can also remove samples from the DataFrame.\n",
    "\n",
    "* We do this with the member function, [my_DataFrame].drop()\n",
    "\n",
    "* We just have the give the sample index and by indicating axis=0 we specify to drop a sample."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>X</th>\n",
       "      <th>Y</th>\n",
       "      <th>facies</th>\n",
       "      <th>porosity</th>\n",
       "      <th>perm</th>\n",
       "      <th>ai</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>565</td>\n",
       "      <td>1485</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1184</td>\n",
       "      <td>6.170</td>\n",
       "      <td>2.009</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2585</td>\n",
       "      <td>1185</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1566</td>\n",
       "      <td>6.275</td>\n",
       "      <td>2.864</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2065</td>\n",
       "      <td>2865</td>\n",
       "      <td>2</td>\n",
       "      <td>0.1920</td>\n",
       "      <td>92.297</td>\n",
       "      <td>3.524</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1835</td>\n",
       "      <td>35</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1766</td>\n",
       "      <td>7.123</td>\n",
       "      <td>4.000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>3375</td>\n",
       "      <td>2525</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1239</td>\n",
       "      <td>1.468</td>\n",
       "      <td>2.337</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      X     Y  facies  porosity    perm     ai\n",
       "0   565  1485       1    0.1184   6.170  2.009\n",
       "1  2585  1185       1    0.1566   6.275  2.864\n",
       "2  2065  2865       2    0.1920  92.297  3.524\n",
       "4  1835    35       1    0.1766   7.123  4.000\n",
       "5  3375  2525       1    0.1239   1.468  2.337"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = df.drop(3,axis=0)                          # remove the zero column\n",
    "df.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Feature Engineering\n",
    "\n",
    "We may want to make new features by using mathematical operators applied to existing features.  \n",
    "\n",
    "* For example, we can make a porosity feature in percentage instead of fraction, called 'porosity100'\n",
    "\n",
    "* Or a ratio of permeability divided by porosity, called 'permpor', may be useful for subsequent calculations such as the Lorenz Coefficient.  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>X</th>\n",
       "      <th>Y</th>\n",
       "      <th>facies</th>\n",
       "      <th>porosity</th>\n",
       "      <th>perm</th>\n",
       "      <th>ai</th>\n",
       "      <th>porosity100</th>\n",
       "      <th>permpor</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>565</td>\n",
       "      <td>1485</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1184</td>\n",
       "      <td>6.170</td>\n",
       "      <td>2.009</td>\n",
       "      <td>11.84</td>\n",
       "      <td>52.111486</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2585</td>\n",
       "      <td>1185</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1566</td>\n",
       "      <td>6.275</td>\n",
       "      <td>2.864</td>\n",
       "      <td>15.66</td>\n",
       "      <td>40.070243</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2065</td>\n",
       "      <td>2865</td>\n",
       "      <td>2</td>\n",
       "      <td>0.1920</td>\n",
       "      <td>92.297</td>\n",
       "      <td>3.524</td>\n",
       "      <td>19.20</td>\n",
       "      <td>480.713542</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1835</td>\n",
       "      <td>35</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1766</td>\n",
       "      <td>7.123</td>\n",
       "      <td>4.000</td>\n",
       "      <td>17.66</td>\n",
       "      <td>40.334088</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>3375</td>\n",
       "      <td>2525</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1239</td>\n",
       "      <td>1.468</td>\n",
       "      <td>2.337</td>\n",
       "      <td>12.39</td>\n",
       "      <td>11.848265</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      X     Y  facies  porosity    perm     ai  porosity100     permpor\n",
       "0   565  1485       1    0.1184   6.170  2.009        11.84   52.111486\n",
       "1  2585  1185       1    0.1566   6.275  2.864        15.66   40.070243\n",
       "2  2065  2865       2    0.1920  92.297  3.524        19.20  480.713542\n",
       "4  1835    35       1    0.1766   7.123  4.000        17.66   40.334088\n",
       "5  3375  2525       1    0.1239   1.468  2.337        12.39   11.848265"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df['porosity100'] = df['porosity']*100          # add a new column with porosity in percentage\n",
    "df['permpor'] = df['perm']/df['porosity']       # add a new feature with ratio of perm / por \n",
    "df.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Conditional Manipulation\n",
    "\n",
    "We could also use conditional statements when assigning values to a new feature.  \n",
    "\n",
    "* For example, we could have a categorical porosity measure for high and low porosity, called 'tporosity'."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>X</th>\n",
       "      <th>Y</th>\n",
       "      <th>facies</th>\n",
       "      <th>porosity</th>\n",
       "      <th>perm</th>\n",
       "      <th>ai</th>\n",
       "      <th>porosity100</th>\n",
       "      <th>permpor</th>\n",
       "      <th>tporosity</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>565</td>\n",
       "      <td>1485</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1184</td>\n",
       "      <td>6.170</td>\n",
       "      <td>2.009</td>\n",
       "      <td>11.84</td>\n",
       "      <td>52.111486</td>\n",
       "      <td>low</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2585</td>\n",
       "      <td>1185</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1566</td>\n",
       "      <td>6.275</td>\n",
       "      <td>2.864</td>\n",
       "      <td>15.66</td>\n",
       "      <td>40.070243</td>\n",
       "      <td>high</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2065</td>\n",
       "      <td>2865</td>\n",
       "      <td>2</td>\n",
       "      <td>0.1920</td>\n",
       "      <td>92.297</td>\n",
       "      <td>3.524</td>\n",
       "      <td>19.20</td>\n",
       "      <td>480.713542</td>\n",
       "      <td>high</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1835</td>\n",
       "      <td>35</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1766</td>\n",
       "      <td>7.123</td>\n",
       "      <td>4.000</td>\n",
       "      <td>17.66</td>\n",
       "      <td>40.334088</td>\n",
       "      <td>high</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>3375</td>\n",
       "      <td>2525</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1239</td>\n",
       "      <td>1.468</td>\n",
       "      <td>2.337</td>\n",
       "      <td>12.39</td>\n",
       "      <td>11.848265</td>\n",
       "      <td>high</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      X     Y  facies  porosity    perm     ai  porosity100     permpor  \\\n",
       "0   565  1485       1    0.1184   6.170  2.009        11.84   52.111486   \n",
       "1  2585  1185       1    0.1566   6.275  2.864        15.66   40.070243   \n",
       "2  2065  2865       2    0.1920  92.297  3.524        19.20  480.713542   \n",
       "4  1835    35       1    0.1766   7.123  4.000        17.66   40.334088   \n",
       "5  3375  2525       1    0.1239   1.468  2.337        12.39   11.848265   \n",
       "\n",
       "  tporosity  \n",
       "0       low  \n",
       "1      high  \n",
       "2      high  \n",
       "4      high  \n",
       "5      high  "
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df['tporosity'] = np.where(df['porosity']>=0.12, 'high', 'low') # make a new categorical feature\n",
    "df.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Conditional Manipulation, More Than One Feature\n",
    "\n",
    "Here's an example where we use a conditional statement to assign a very low permeability value (0.0001 mD) for all porosity values below a threshold. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>X</th>\n",
       "      <th>Y</th>\n",
       "      <th>facies</th>\n",
       "      <th>porosity</th>\n",
       "      <th>perm</th>\n",
       "      <th>ai</th>\n",
       "      <th>porosity100</th>\n",
       "      <th>permpor</th>\n",
       "      <th>tporosity</th>\n",
       "      <th>perm_cutoff</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>565</td>\n",
       "      <td>1485</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1184</td>\n",
       "      <td>6.170</td>\n",
       "      <td>2.009</td>\n",
       "      <td>11.84</td>\n",
       "      <td>52.111486</td>\n",
       "      <td>low</td>\n",
       "      <td>0.0001</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2585</td>\n",
       "      <td>1185</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1566</td>\n",
       "      <td>6.275</td>\n",
       "      <td>2.864</td>\n",
       "      <td>15.66</td>\n",
       "      <td>40.070243</td>\n",
       "      <td>high</td>\n",
       "      <td>6.2750</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2065</td>\n",
       "      <td>2865</td>\n",
       "      <td>2</td>\n",
       "      <td>0.1920</td>\n",
       "      <td>92.297</td>\n",
       "      <td>3.524</td>\n",
       "      <td>19.20</td>\n",
       "      <td>480.713542</td>\n",
       "      <td>high</td>\n",
       "      <td>92.2970</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1835</td>\n",
       "      <td>35</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1766</td>\n",
       "      <td>7.123</td>\n",
       "      <td>4.000</td>\n",
       "      <td>17.66</td>\n",
       "      <td>40.334088</td>\n",
       "      <td>high</td>\n",
       "      <td>7.1230</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>3375</td>\n",
       "      <td>2525</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1239</td>\n",
       "      <td>1.468</td>\n",
       "      <td>2.337</td>\n",
       "      <td>12.39</td>\n",
       "      <td>11.848265</td>\n",
       "      <td>high</td>\n",
       "      <td>1.4680</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      X     Y  facies  porosity    perm     ai  porosity100     permpor  \\\n",
       "0   565  1485       1    0.1184   6.170  2.009        11.84   52.111486   \n",
       "1  2585  1185       1    0.1566   6.275  2.864        15.66   40.070243   \n",
       "2  2065  2865       2    0.1920  92.297  3.524        19.20  480.713542   \n",
       "4  1835    35       1    0.1766   7.123  4.000        17.66   40.334088   \n",
       "5  3375  2525       1    0.1239   1.468  2.337        12.39   11.848265   \n",
       "\n",
       "  tporosity  perm_cutoff  \n",
       "0       low       0.0001  \n",
       "1      high       6.2750  \n",
       "2      high      92.2970  \n",
       "4      high       7.1230  \n",
       "5      high       1.4680  "
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df['perm_cutoff'] = np.where(df['porosity']>=0.12, df['perm'],0.0001) # new feature with conditional truncation\n",
    "df.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Finding Missing Data\n",
    "\n",
    "What about missing or invalid values? \n",
    "\n",
    "* Let's assign a single porosity value to NaN, 'not a number', indicating a missing or eroneous value.  \n",
    "\n",
    "* We will then check for the number of NaN values in our DataFrame.  \n",
    "\n",
    "* Then we can search for and display the sample with the NaN porosity value."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Number of null values in our DataFrame =  1\n",
      "      X     Y  facies  porosity   perm     ai  porosity100    permpor  \\\n",
      "1  2585  1185       1       NaN  6.275  2.864        15.66  40.070243   \n",
      "\n",
      "  tporosity  perm_cutoff  \n",
      "1      high        6.275  \n"
     ]
    }
   ],
   "source": [
    "df.loc[1,'porosity'] = np.NaN                   # add a NaN / missing value in our table\n",
    "print('Number of null values in our DataFrame = ', str(df.isnull().sum().sum())) # count missing values \n",
    "nan_rows = df[df['porosity'].isnull()]          # find the sample with missing values\n",
    "print(nan_rows)                                 # print this sample"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Likewise Deletion\n",
    "\n",
    "We can see that sample 1 has a NaN porosity value.  Now we may choose to remove the sample with the NaN.  \n",
    "\n",
    "* The 'dropna' DataFrame member function will remove all samples with NaN entries from the entire DataFrame.  \n",
    "\n",
    "* By visualizing the index at the left of the DataFrame preview you can confirm that sample 1 is removed (it jumps from 0 to 2)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>X</th>\n",
       "      <th>Y</th>\n",
       "      <th>facies</th>\n",
       "      <th>porosity</th>\n",
       "      <th>perm</th>\n",
       "      <th>ai</th>\n",
       "      <th>porosity100</th>\n",
       "      <th>permpor</th>\n",
       "      <th>tporosity</th>\n",
       "      <th>perm_cutoff</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>565</td>\n",
       "      <td>1485</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1184</td>\n",
       "      <td>6.170</td>\n",
       "      <td>2.009</td>\n",
       "      <td>11.84</td>\n",
       "      <td>52.111486</td>\n",
       "      <td>low</td>\n",
       "      <td>0.0001</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2065</td>\n",
       "      <td>2865</td>\n",
       "      <td>2</td>\n",
       "      <td>0.1920</td>\n",
       "      <td>92.297</td>\n",
       "      <td>3.524</td>\n",
       "      <td>19.20</td>\n",
       "      <td>480.713542</td>\n",
       "      <td>high</td>\n",
       "      <td>92.2970</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1835</td>\n",
       "      <td>35</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1766</td>\n",
       "      <td>7.123</td>\n",
       "      <td>4.000</td>\n",
       "      <td>17.66</td>\n",
       "      <td>40.334088</td>\n",
       "      <td>high</td>\n",
       "      <td>7.1230</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>3375</td>\n",
       "      <td>2525</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1239</td>\n",
       "      <td>1.468</td>\n",
       "      <td>2.337</td>\n",
       "      <td>12.39</td>\n",
       "      <td>11.848265</td>\n",
       "      <td>high</td>\n",
       "      <td>1.4680</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>2295</td>\n",
       "      <td>1325</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1790</td>\n",
       "      <td>31.933</td>\n",
       "      <td>3.491</td>\n",
       "      <td>17.90</td>\n",
       "      <td>178.396648</td>\n",
       "      <td>high</td>\n",
       "      <td>31.9330</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      X     Y  facies  porosity    perm     ai  porosity100     permpor  \\\n",
       "0   565  1485       1    0.1184   6.170  2.009        11.84   52.111486   \n",
       "2  2065  2865       2    0.1920  92.297  3.524        19.20  480.713542   \n",
       "4  1835    35       1    0.1766   7.123  4.000        17.66   40.334088   \n",
       "5  3375  2525       1    0.1239   1.468  2.337        12.39   11.848265   \n",
       "6  2295  1325       1    0.1790  31.933  3.491        17.90  178.396648   \n",
       "\n",
       "  tporosity  perm_cutoff  \n",
       "0       low       0.0001  \n",
       "2      high      92.2970  \n",
       "4      high       7.1230  \n",
       "5      high       1.4680  \n",
       "6      high      31.9330  "
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = df.dropna(how='any')                       # drop any rows (samples) with atleast one missing value        \n",
    "df.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Conditional Slicing\n",
    "\n",
    "One could extract samples into a new DataFrame with multiple criteria.\n",
    "\n",
    "* We make a new DataFrame with all good porosity and good permeability"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>X</th>\n",
       "      <th>Y</th>\n",
       "      <th>facies</th>\n",
       "      <th>porosity</th>\n",
       "      <th>perm</th>\n",
       "      <th>ai</th>\n",
       "      <th>porosity100</th>\n",
       "      <th>permpor</th>\n",
       "      <th>tporosity</th>\n",
       "      <th>perm_cutoff</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2065</td>\n",
       "      <td>2865</td>\n",
       "      <td>2</td>\n",
       "      <td>0.1920</td>\n",
       "      <td>92.297</td>\n",
       "      <td>3.524</td>\n",
       "      <td>19.20</td>\n",
       "      <td>480.713542</td>\n",
       "      <td>high</td>\n",
       "      <td>92.297</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>2295</td>\n",
       "      <td>1325</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1790</td>\n",
       "      <td>31.933</td>\n",
       "      <td>3.491</td>\n",
       "      <td>17.90</td>\n",
       "      <td>178.396648</td>\n",
       "      <td>high</td>\n",
       "      <td>31.933</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>3715</td>\n",
       "      <td>3045</td>\n",
       "      <td>2</td>\n",
       "      <td>0.1914</td>\n",
       "      <td>116.781</td>\n",
       "      <td>2.187</td>\n",
       "      <td>19.14</td>\n",
       "      <td>610.141066</td>\n",
       "      <td>high</td>\n",
       "      <td>116.781</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13</th>\n",
       "      <td>545</td>\n",
       "      <td>3765</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1817</td>\n",
       "      <td>14.311</td>\n",
       "      <td>3.045</td>\n",
       "      <td>18.17</td>\n",
       "      <td>78.761695</td>\n",
       "      <td>high</td>\n",
       "      <td>14.311</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>15</th>\n",
       "      <td>1385</td>\n",
       "      <td>2415</td>\n",
       "      <td>2</td>\n",
       "      <td>0.1774</td>\n",
       "      <td>22.578</td>\n",
       "      <td>2.711</td>\n",
       "      <td>17.74</td>\n",
       "      <td>127.271702</td>\n",
       "      <td>high</td>\n",
       "      <td>22.578</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "       X     Y  facies  porosity     perm     ai  porosity100     permpor  \\\n",
       "2   2065  2865       2    0.1920   92.297  3.524        19.20  480.713542   \n",
       "6   2295  1325       1    0.1790   31.933  3.491        17.90  178.396648   \n",
       "7   3715  3045       2    0.1914  116.781  2.187        19.14  610.141066   \n",
       "13   545  3765       1    0.1817   14.311  3.045        18.17   78.761695   \n",
       "15  1385  2415       2    0.1774   22.578  2.711        17.74  127.271702   \n",
       "\n",
       "   tporosity  perm_cutoff  \n",
       "2       high       92.297  \n",
       "6       high       31.933  \n",
       "7       high      116.781  \n",
       "13      high       14.311  \n",
       "15      high       22.578  "
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_extract = df.loc[(df['porosity'] > 0.12) & (df['perm'] > 10.0)] # extract with multiple conditions to a new table\n",
    "df_extract.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Making a New DataFrame from Scratch\n",
    "\n",
    "It is also simple to build a new DataFrame from a set of 1D arrays.  \n",
    "\n",
    "* Note, they must have the same size and be sorted consistently.  \n",
    "\n",
    "* We will extract porosity and perm as arrays (if you remove '.values' they are extracted as Series, an array retaining the feature name).  \n",
    "\n",
    "* We then use the pandas DataFrame command to make a new DataFrame with each 1D array and the column names specified as 'porosity' and 'permeability'."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>porosity</th>\n",
       "      <th>permeability</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0.1184</td>\n",
       "      <td>6.170</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0.1920</td>\n",
       "      <td>92.297</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0.1766</td>\n",
       "      <td>7.123</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0.1239</td>\n",
       "      <td>1.468</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0.1790</td>\n",
       "      <td>31.933</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   porosity  permeability\n",
       "0    0.1184         6.170\n",
       "1    0.1920        92.297\n",
       "2    0.1766         7.123\n",
       "3    0.1239         1.468\n",
       "4    0.1790        31.933"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "por = df['porosity'].values                     # extract porosity column as vector\n",
    "perm = df['perm'].values                        # extract permeability column as vector\n",
    "df_new = pd.DataFrame({'porosity': por, 'permeability': perm}) # make a new DataFrame from the vectors\n",
    "df_new.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Basic Plotting\n",
    "\n",
    "While I generally use MatPlotLib, Seaborn etc. for plotting, Pandas has built in plotting functions.\n",
    "\n",
    "#### Line Plots\n",
    "\n",
    "Here's an example of a line plot.\n",
    "\n",
    "* there are various other types to choose from, e.g. bar, box, scatter etc."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "df['porosity'].plot(kind='line',color='red')    # make a line plot\n",
    "plt.ylabel('Porosity (fraction)'); plt.xlabel('Sample'); plt.title('DataFrame Feature Line Plot'); plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Histograms\n",
    "\n",
    "Here's an example of a histogram."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "df['porosity'].plot(kind = 'hist',color='red',edgecolor='black') # plot a histogram\n",
    "plt.ylabel('Porosity (fraction)'); plt.xlabel('Sample'); plt.title('DataFrame Feature Histogram'); plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Accessing the DataFrame Members\n",
    "\n",
    "We can reach in and retrieve the actual raw information in the DataFrame including the column names and actual values as an numpy array. We can't edit them like this, but we can access and use this information. This includes: \n",
    "\n",
    "* 'index' with information about the sample index \n",
    "* 'columns' with the names of the features \n",
    "* 'values' with the data table entries as a 2D array.   "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Int64Index([  0,   2,   4,   5,   6,   7,   8,   9,  10,  11,\n",
      "            ...\n",
      "            190, 191, 192, 193, 194, 195, 196, 197, 198, 199],\n",
      "           dtype='int64', length=198)\n",
      "Index(['X', 'Y', 'facies', 'porosity', 'perm', 'ai', 'porosity100', 'permpor',\n",
      "       'tporosity', 'perm_cutoff'],\n",
      "      dtype='object')\n",
      "[[565 1485 1 ... 52.111486486486484 'low' 0.0001]\n",
      " [2065 2865 2 ... 480.71354166666674 'high' 92.29700000000001]\n",
      " [1835 35 1 ... 40.334088335220834 'high' 7.122999999999999]\n",
      " ...\n",
      " [375 1705 1 ... 18.198334595003786 'high' 2.404]\n",
      " [3795 535 1 ... 0.25968483256730135 'low' 0.0001]\n",
      " [3455 1645 1 ... 6.578073089700997 'high' 0.99]]\n"
     ]
    }
   ],
   "source": [
    "print(df.index)                                 # get information about the index\n",
    "print(df.columns)                               # get the list of feature names\n",
    "print(df.values)                                # get the 2D array with all the table data"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Retrieving Values DataFrames with [my_DataFrame].values()\n",
    "\n",
    "We can read values through the values member of DataFrames"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Porosity value for sample number 0 is 0.1184.\n"
     ]
    }
   ],
   "source": [
    "por1 = df.values[0,3]                           # get the value for sample 1 of the 4th feature (porosity)\n",
    "print('Porosity value for sample number 0 is ' + str(por1) + '.') "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Converting a Pandas DataFrame to a NumPy ndarry\n",
    "\n",
    "We can copy the entire DataFrame to a ndarray."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "We just made a <class 'numpy.ndarray'>\n",
      "of shape (198, 10)\n"
     ]
    }
   ],
   "source": [
    "df_array = df.to_numpy()                        # copy the DataFrame to an ndarray\n",
    "print('We just made a ' + str(type(df_array)))  \n",
    "print('of shape ' + str(df_array.shape))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note this is a deep copy. If we change the ndarray, the DataFrame is not updated."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>X</th>\n",
       "      <th>Y</th>\n",
       "      <th>facies</th>\n",
       "      <th>porosity</th>\n",
       "      <th>perm</th>\n",
       "      <th>ai</th>\n",
       "      <th>porosity100</th>\n",
       "      <th>permpor</th>\n",
       "      <th>tporosity</th>\n",
       "      <th>perm_cutoff</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>565</td>\n",
       "      <td>1485</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1184</td>\n",
       "      <td>6.170</td>\n",
       "      <td>2.009</td>\n",
       "      <td>11.84</td>\n",
       "      <td>52.111486</td>\n",
       "      <td>low</td>\n",
       "      <td>0.0001</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2065</td>\n",
       "      <td>2865</td>\n",
       "      <td>2</td>\n",
       "      <td>0.1920</td>\n",
       "      <td>92.297</td>\n",
       "      <td>3.524</td>\n",
       "      <td>19.20</td>\n",
       "      <td>480.713542</td>\n",
       "      <td>high</td>\n",
       "      <td>92.2970</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1835</td>\n",
       "      <td>35</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1766</td>\n",
       "      <td>7.123</td>\n",
       "      <td>4.000</td>\n",
       "      <td>17.66</td>\n",
       "      <td>40.334088</td>\n",
       "      <td>high</td>\n",
       "      <td>7.1230</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      X     Y  facies  porosity    perm     ai  porosity100     permpor  \\\n",
       "0   565  1485       1    0.1184   6.170  2.009        11.84   52.111486   \n",
       "2  2065  2865       2    0.1920  92.297  3.524        19.20  480.713542   \n",
       "4  1835    35       1    0.1766   7.123  4.000        17.66   40.334088   \n",
       "\n",
       "  tporosity  perm_cutoff  \n",
       "0       low       0.0001  \n",
       "2      high      92.2970  \n",
       "4      high       7.1230  "
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_array[2,1] = 10000                           # change an element of the ndarray\n",
    "df.head(n=3)                                    # check the original DataFrame"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Python Built-in Functions on DataFrames\n",
    "\n",
    "There are some Python built-in functions that accept a DataFrame as an argument."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The DataFrame has 198 samples.\n",
      "The DataFrame's features are ['X', 'Y', 'facies', 'porosity', 'perm', 'ai', 'porosity100', 'permpor', 'tporosity', 'perm_cutoff'].\n"
     ]
    }
   ],
   "source": [
    "print('The DataFrame has ' + str(len(df)) + ' samples.') # number of samples\n",
    "print('The DataFrame\\'s features are ' + str(list(df)) + '.') # list of the features "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Directly Editing DataFrames\n",
    "\n",
    "Let's interact with the DataFrame more surgically, one feature and sample at a time.  \n",
    "\n",
    "* We can use the [my_DataFrame].at() member function to access a single value\n",
    "\n",
    "* This includes reading and writing\n",
    "\n",
    "* Alternatively we could use [my_DataFrame].loc(), used previously"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The value of the first porosity sample was 0.1184\n",
      "The value of porosity for sample 0 is now 0.2.\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>X</th>\n",
       "      <th>Y</th>\n",
       "      <th>facies</th>\n",
       "      <th>porosity</th>\n",
       "      <th>perm</th>\n",
       "      <th>ai</th>\n",
       "      <th>porosity100</th>\n",
       "      <th>permpor</th>\n",
       "      <th>tporosity</th>\n",
       "      <th>perm_cutoff</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>565</td>\n",
       "      <td>1485</td>\n",
       "      <td>1</td>\n",
       "      <td>0.2000</td>\n",
       "      <td>6.170</td>\n",
       "      <td>2.009</td>\n",
       "      <td>11.84</td>\n",
       "      <td>52.111486</td>\n",
       "      <td>low</td>\n",
       "      <td>0.0001</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2065</td>\n",
       "      <td>2865</td>\n",
       "      <td>2</td>\n",
       "      <td>0.1920</td>\n",
       "      <td>92.297</td>\n",
       "      <td>3.524</td>\n",
       "      <td>19.20</td>\n",
       "      <td>480.713542</td>\n",
       "      <td>high</td>\n",
       "      <td>92.2970</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1835</td>\n",
       "      <td>35</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1766</td>\n",
       "      <td>7.123</td>\n",
       "      <td>4.000</td>\n",
       "      <td>17.66</td>\n",
       "      <td>40.334088</td>\n",
       "      <td>high</td>\n",
       "      <td>7.1230</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>3375</td>\n",
       "      <td>2525</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1239</td>\n",
       "      <td>1.468</td>\n",
       "      <td>2.337</td>\n",
       "      <td>12.39</td>\n",
       "      <td>11.848265</td>\n",
       "      <td>high</td>\n",
       "      <td>1.4680</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>2295</td>\n",
       "      <td>1325</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1790</td>\n",
       "      <td>31.933</td>\n",
       "      <td>3.491</td>\n",
       "      <td>17.90</td>\n",
       "      <td>178.396648</td>\n",
       "      <td>high</td>\n",
       "      <td>31.9330</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      X     Y  facies  porosity    perm     ai  porosity100     permpor  \\\n",
       "0   565  1485       1    0.2000   6.170  2.009        11.84   52.111486   \n",
       "2  2065  2865       2    0.1920  92.297  3.524        19.20  480.713542   \n",
       "4  1835    35       1    0.1766   7.123  4.000        17.66   40.334088   \n",
       "5  3375  2525       1    0.1239   1.468  2.337        12.39   11.848265   \n",
       "6  2295  1325       1    0.1790  31.933  3.491        17.90  178.396648   \n",
       "\n",
       "  tporosity  perm_cutoff  \n",
       "0       low       0.0001  \n",
       "2      high      92.2970  \n",
       "4      high       7.1230  \n",
       "5      high       1.4680  \n",
       "6      high      31.9330  "
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print('The value of the first porosity sample was ' + str(df.at[0,'porosity']))\n",
    "df.at[0,'porosity'] = 0.2000                          # set the value for sample 1 of the porosity feature\n",
    "print('The value of porosity for sample 0 is now ' + str(df.loc[0,'porosity']) + '.')\n",
    "df.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Saving a DataFrame to a File\n",
    "\n",
    "It may be useful to write the DataFrame out for storage or curation and / or to be utilize with another platform (even R or Excel!).  \n",
    "\n",
    "* It is easy to write the DataFrame back to a comma delimited file and other file formats. \n",
    "* We use the DataFrame member function, [my_DataFrame].to_csv()  \n",
    "* The file will write to the working directory (another reason we set that at the beginning).  \n",
    "\n",
    "Go to that folder and open this new file with TextPad, Excel or any other program that opens .txt files to check it out."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [],
   "source": [
    "df.to_csv(\"2D_MV_200wells_out.csv\")             # write out the df DataFrame to a comma delimited file "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "I hope this we helpful,\n",
    "\n",
    "Michael\n",
    "\n",
    "#### More About The Author:\n",
    "\n",
    "### Michael Pyrcz, Associate Professor, The University of Texas at Austin \n",
    "*Novel Data Analytics, Geostatistics and Machine Learning Subsurface Solutions*\n",
    "\n",
    "With over 17 years of experience in subsurface consulting, research and development, Michael has returned to academia driven by his passion for teaching and enthusiasm for enhancing engineers' and geoscientists' impact in subsurface resource development. \n",
    "\n",
    "For more about Michael check out these links:\n",
    "\n",
    "#### [Twitter](https://twitter.com/geostatsguy) | [GitHub](https://github.com/GeostatsGuy) | [Website](http://michaelpyrcz.com) | [GoogleScholar](https://scholar.google.com/citations?user=QVZ20eQAAAAJ&hl=en&oi=ao) | [Book](https://www.amazon.com/Geostatistical-Reservoir-Modeling-Michael-Pyrcz/dp/0199731446) | [YouTube](https://www.youtube.com/channel/UCLqEr-xV-ceHdXXXrTId5ig)  | [LinkedIn](https://www.linkedin.com/in/michael-pyrcz-61a648a1)\n",
    "\n",
    "#### Want to Work Together?\n",
    "\n",
    "I hope this content is helpful to those that want to learn more about subsurface modeling, data analytics and machine learning. Students and working professionals are welcome to participate.\n",
    "\n",
    "* Want to invite me to visit your company for training, mentoring, project review, workflow design and / or consulting? I'd be happy to drop by and work with you! \n",
    "\n",
    "* Interested in partnering, supporting my graduate student research or my Subsurface Data Analytics and Machine Learning consortium (co-PIs including Profs. Foster, Torres-Verdin and van Oort)? My research combines data analytics, stochastic modeling and machine learning theory with practice to develop novel methods and workflows to add value. We are solving challenging subsurface problems!\n",
    "\n",
    "* I can be reached at mpyrcz@austin.utexas.edu.\n",
    "\n",
    "I'm always happy to discuss,\n",
    "\n",
    "*Michael*\n",
    "\n",
    "Michael Pyrcz, Ph.D., P.Eng. Associate Professor The Hildebrand Department of Petroleum and Geosystems Engineering, Bureau of Economic Geology, The Jackson School of Geosciences, The University of Texas at Austin"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
